/*###################################################################*
#
# MP (Mitchell Pell) Base - CrossPlatform Base Utilities.
# Copyright (C) 2014  Mitchell Pell
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
####################################################################*/
#ifndef GL_TCP_SESSION_H
#define GL_TCP_SESSION_H

#include <exception>
#include <vector>
#include "TcpConnection.h"
#include "../../../GLDriver/GLDriverComponents/Console/GLConsole.h"
#include "../../../Base/Updateable.h"
#include "../../../Base/LockableMutex.h"
#include "../../../Base/Pause.h"
#define TCP_SESSION_DEBUG 3

using namespace boost::asio;
using mp_base::interfaces::Updateable;
using mp_base::interfaces::LockableMutex;
using mp_base::utility::Pause;
using mpgl_engine::driver::gl_console::GlConsole;

namespace mpgl_engine { namespace application{ namespace net {

	/*!----------------------------------------------------------------
	*	@enum		TcpSessionType
	*	@brief		Enumeration representing a TCP session type.
	*
	*	@author		Mitchell Pell
	*	@date		01/04/2014
	-----------------------------------------------------------------*/
	enum TcpSessionType
	{
		/*! TCP Client */
		CLIENT	= 0x00,
		/*! TCP Server */
		SERVER	= 0x01,
		/*! TCP Host */
		HOST	= 0x02,
		/*! Unknown Type */
		UNKNOWN = 0xFF
	};

	/*!----------------------------------------------------------------
	*	@class		TcpSession
	*	@brief		This class represents a TCP Session in which one
	*				ore more TCP Connections are held and managed.
	*
	*	@author		Mitchell Pell
	*	@date		01/07/2014
	*	@version	1.1
	*
	*	@revisions	Revision History:
	*
	*					- Version 1.1 01/08/2014
	*						-# Added update loop for connections.
	*
	*					- Version 1.0 01/04/2014
	*						-# Initial Make
	*
	-----------------------------------------------------------------*/
	class TcpSession : public Updateable, public LockableMutex
	{
		/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		>>  Constructors / Destructor
		/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
	protected:
		/*!  */
		TcpSession(GlConsole* console = NULL,
			io_service* ioService = NULL,
			TcpSessionType sessionType
			= TcpSessionType::UNKNOWN,
			uint maxConnections = 1);
	public:

		/*!  */
		virtual ~TcpSession();

		/*!  */
		void SetIOService(io_service* ioService){
			m_ioService = ioService;}

		/*!  */
		virtual void Initialize(){ m_initialized = true; }
		/*!  */
		virtual void Update();

		/*!  */
		virtual void Disconnect() = 0;
		/*!  */
		virtual void Connect() = 0;

		/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		>>  Accessors / Mutators
		/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
	public:

		/*!  */
		const TcpSessionType GetSessionType() const {
			return m_sessionType; }

		/*!  */
		void SetConsole(GlConsole* console){ m_console = console; }

	protected:

		/*!  */
		void SetSessionType(TcpSessionType sessionType){
			m_sessionType = sessionType;}


		/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		>>  Members
		/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
	protected:

		/*! Collection of TCP Connections. */
		std::vector<TcpConnection*> m_connections;
		/*! IO service for all network operations. */
		io_service*					m_ioService;
		/*! Session type identifier. */
		TcpSessionType				m_sessionType;
		/*! Max connections supported in this session. */
		uint						m_maxConnections;
		/*! Session stop request flag.  */
		volatile bool				m_stopRequest;
		/*! GlConsole for messages and commands. */
		GlConsole*					m_console;
	};
}}}

#endif